package javango.db;

import java.io.Serializable;
import java.util.Iterator;
import java.util.List;

/**
 * Defines a base line of functionality for querying for objects,  no attempt is made at an exaustive function set as the underling
 * provider will give much more flexability.  Subclasses should feel free to expose additional functionality.  For example the
 * hibernate implementation could provide a getCriteria that returns the current hibernate criteria.
 * 
 * This is an expiremental package
 * 
 * @author johns
 *
 */
public interface QuerySet<T> extends Iterable<T> {

	QuerySet<T> filter(Object args) throws ManagerException;
	QuerySet<T> filter(String property, Object value) throws ManagerException;
	List<T> list() throws ManagerException;
	long count() throws ManagerException;
	
	/**
	 * Limit the query to only contain those records between first and last inclusive
	 * 
	 * @param first The first record to return (record 1 is the first record)
	 * @param last The last record to return (record 1 is the first record)
	 * @return
	 * @throws ManagerException
	 */
	QuerySet<T> limit(int first, int last) throws ManagerException;
	public Iterator<T> iterator();
	
	/**
	 * Returns a single object selected by this queryset,  if no matching object is found,  or if multiple objects match this queryset an exception will be thrown.
	 * 
	 * @return
	 * @throws ManagerException
	 */
	T get() throws ManagerException;
	
	/**
	 * Order by the specified properties,  if a property starts with a '-' it will be descending.
	 * 
	 * Example: orderBy("name", "-birthDate");
	 * 
	 * @param property
	 * @return
	 */
	QuerySet<T> orderBy(String... property) throws ManagerException;
	
}
